package ug.co.icom.kyazze.healthticket;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import ug.co.icom.kyazze.healthticket.data.User;
import ug.co.icom.kyazze.healthticket.images.IntentProfileImageService;
import ug.co.icom.kyazze.healthticket.mongoHQ.MongoHQMedicalRecord;
import ug.co.icom.kyazze.healthticket.mongoHQ.MongoHQRegister;
import ug.co.icom.kyazze.healthticket.mongoHQ.UploadToServer;
import ug.co.icom.kyazze.healthticket.services.ApplicationObject;
import ug.co.icom.kyazze.healthticket.services.IntentMRecordService;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;

/**
 * Registers a new PHR owner
 * 
 * @author KYAZZE MICHAEL
 * 
 */
public class RegisterActivity extends Activity implements OnClickListener {

	private static final int DATE_DIALOG_ID = 999;
	private User user;
	private Button registerButton;
	private Spinner countryCode;
	private EditText phonenumber;
	private EditText firstname;
	private EditText lastname;
	private EditText password;
	private EditText email;
	private TextView dateofbirth;
	private ToggleButton female;
	private int year;
	private int month;
	private int day;
	private Bitmap bitmap;
	private ImageButton image;
	private ImageButton selectImageButton;
	@SuppressWarnings("unused")
	private String ImageName;
	private static final int PICK_IMAGE = 1;
	private String filepath = "healthTicket_files";
	File myInternalFile;
	File directory;
	long val = 999;
	Locale locale = Locale.getDefault();
	ByteArrayOutputStream bs;

	@SuppressLint("CutPasteId")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.registeractivity_layout);

		registerButton = (Button) findViewById(R.id.button1);
		registerButton.setOnClickListener(this);
		dateofbirth = (TextView) findViewById(R.id.textView2);
		dateofbirth.setOnClickListener(this);
		countryCode = (Spinner) findViewById(R.id.spinner2);
		phonenumber = (EditText) findViewById(R.id.editText1);
		password = (EditText) findViewById(R.id.editText2);
		firstname = (EditText) findViewById(R.id.editText3);
		lastname = (EditText) findViewById(R.id.editText4);
		email = (EditText) findViewById(R.id.editText6);
		female = (ToggleButton) findViewById(R.id.toggleButton1);
		ContextWrapper contextWrapper = new ContextWrapper(
				getApplicationContext());
		directory = contextWrapper.getDir(filepath, Context.MODE_PRIVATE);
		directory.mkdir();
		ApplicationObject mApplication = (ApplicationObject) getApplicationContext();
		mApplication.setDirectory(directory);
		setCurrentDateOnView();

		image = (ImageButton) findViewById(R.id.selectImageButton);
		// on click select an image
		selectImageButton = (ImageButton) findViewById(R.id.selectImageButton);
		selectImageButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				selectImageFromGallery();
			}

		});
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.button1) {
			if (allRequiredDetailsExist()) {
				try {
					user = new User();
					user.PhoneNumber = generatePhoneNumber(countryCode
							.getSelectedItem().toString(), phonenumber
							.getText().toString());
					user.PassCode = password.getText().toString();
					user.FirstName = firstname.getText().toString();
					user.LastName = lastname.getText().toString();
					user.DateOfBirth = getDateFromString(dateofbirth.getText()
							.toString());
					user.Email = email.getText().toString();
					user.Female = female.isChecked();

					ApplicationObject mApplication = (ApplicationObject) getApplicationContext();
					mApplication.setphone_number(Long
							.parseLong(user.PhoneNumber));
					// TODO Create medical doc, encrypt and upload id pass id
					// url as argument to user.medical_id

					// created medical doc and obtained its id

					Crouton.makeText(this, "Registration in Progress",
							Style.INFO).show();

					MongoHQMedicalRecord mh = new MongoHQMedicalRecord();
					mh.execute(user.PhoneNumber, directory);
					// upload text file (test: before encryption)

					Intent intent_service = new Intent(this,
							IntentMRecordService.class);
					intent_service.putExtra("Pnumber", user.PhoneNumber);
					startService(intent_service);

					// CP-ABE
					// String inputfile =
					// Environment.getExternalStorageDirectory().getPath()+"/healthTicket_files/"+user.PhoneNumber+".txt";
					// String pubfile =
					// Environment.getExternalStorageDirectory().getPath()+"/healthTicket_files/"+user.PhoneNumber+"pub_key";
					// String mskfile =
					// Environment.getExternalStorageDirectory().getPath()+"/healthTicket_files/"+user.PhoneNumber+"master_key";
					// String encfile =
					// Environment.getExternalStorageDirectory().getPath()+"/healthTicket_files/"+user.PhoneNumber+".cpabe";
					//
					// String inputfile = directory+"/"+user.PhoneNumber+".txt";
					// String pubfile =
					// directory+"/"+user.PhoneNumber+"pub_key";
					// String mskfile =
					// directory+"/"+user.PhoneNumber+"master_key";
					// String encfile = directory+"/"+user.PhoneNumber+".cpabe";
					// String prvfile =
					// directory+"/"+user.PhoneNumber+"prv_key";
					//
					// String main_attribute_set =
					// "objectClass:inetOrgPerson objectClass:organizationalPerson "
					// +
					// "sn:student2 cn:student2 uid:student2 userPassword:student2 "
					// +
					// "ou:idp o:computer mail:student2@sdu.edu.cn title:student";
					// String student_policy =
					// "sn:student2 cn:student2 uid:student2 3of3";
					// String policy = "";
					// policy = student_policy;
					//
					// Cpabe test = new Cpabe();
					// try {
					// test.setup(pubfile, mskfile);
					// //keygen here
					// test.enc(pubfile, policy, inputfile, encfile);
					//
					// //generate private key
					// test.keygen(pubfile, prvfile, mskfile,
					// main_attribute_set);
					//
					//
					// } catch (Exception e) {
					// // TODO Auto-generated catch block
					// e.printStackTrace();
					// }
					//

					// UploadToServer xy = new UploadToServer();
					// xy.execute(user.PhoneNumber);

					user.Medical_id = "http://appitconsult.com/healthticket/keyfile"
							+ "/" + user.PhoneNumber + ".cpabe";

					// ........................................................

					Crouton.makeText(this, "Data Encryption in Progress",
							Style.INFO).show();

					MongoHQRegister mhr = new MongoHQRegister();
					Boolean ret = mhr.execute(user).get();

					if (ret) {
						AlertDialog.Builder builder = new AlertDialog.Builder(
								RegisterActivity.this);
						builder.setMessage("You have been successfully registered");
						builder.setCancelable(true);
						builder.setPositiveButton("Ok",
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										dialog.cancel();

										finish();
									}
								});
						AlertDialog alert = builder.create();
						alert.show();
					} else {
						AlertDialog.Builder builder = new AlertDialog.Builder(
								RegisterActivity.this);
						builder.setMessage("An error occurred while registering you");
						builder.setCancelable(true);
						builder.setPositiveButton("Ok",
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										dialog.cancel();

									}
								});
						AlertDialog alert = builder.create();
						alert.show();
					}
				} catch (Exception e) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							RegisterActivity.this);
					builder.setMessage("An error occurred while registering you");
					builder.setCancelable(true);
					builder.setPositiveButton("Ok",
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									dialog.cancel();

								}
							});
					AlertDialog alert = builder.create();
					alert.show();
				}
			} else {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						RegisterActivity.this);
				builder.setMessage("Please Provide all the required Data");
				builder.setCancelable(true);
				builder.setPositiveButton("Ok",
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.cancel();
							}
						});
				AlertDialog alert = builder.create();
				alert.show();
			}
		} else if (v.getId() == R.id.textView2) {
			showDialog(DATE_DIALOG_ID);
		}

		/**
		 * Uploads Image to server
		 */
//		Intent s_service = new Intent(RegisterActivity.this,
//				IntentProfileImageService.class);
//		// pass bitmap object
//		Bitmap b = bitmap; // your bitmap
//		bs = new ByteArrayOutputStream();
//		b.compress(Bitmap.CompressFormat.PNG, 50, bs);
//		s_service.putExtra("byteArray", bs.toByteArray());
//		startService(s_service);
		
		/**
		 * Store image in SQLite db first
		 */
		ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
		directory = contextWrapper.getDir(filepath, Context.MODE_PRIVATE);
		
		//Bitmap b = bitmap; // your bitmap
		bs = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bs);
		
		File SDCardRoot = new File(directory + "/");
		File file = new File(SDCardRoot, "kyazze.jpg");
		try {
			filesave(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private Date getDateFromString(String dateReceived) {
		SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy", locale);
		try {
			Date date = format.parse(dateReceived);
			return date;
		} catch (Exception e) {
			return new Date();
		}
	}

	private String generatePhoneNumber(String countryCode, String phoneNumber) {
		// remove leading zero if provided
		String pn = phoneNumber.startsWith("0") ? phoneNumber.substring(1)
				: phoneNumber;
		return countryCode + pn;
	}

	private Boolean allRequiredDetailsExist() {
		return true;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DATE_DIALOG_ID:
			// set date picker as current date
			return new DatePickerDialog(this, datePickerListener, year, month,
					day);
		}
		return null;
	}

	private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() {

		// when dialog box is closed, below method will be called.
		public void onDateSet(DatePicker view, int selectedYear,
				int selectedMonth, int selectedDay) {
			year = selectedYear;
			month = selectedMonth;
			day = selectedDay;

			// set selected date into textview
			dateofbirth.setText(new StringBuilder().append(day).append("-")
					.append(month + 1).append("-").append(year));
		}
	};

	// display current date
	public void setCurrentDateOnView() {

		final Calendar c = Calendar.getInstance();
		year = c.get(Calendar.YEAR);
		month = c.get(Calendar.MONTH);
		day = c.get(Calendar.DAY_OF_MONTH);

		// set current date into textview
		dateofbirth.setText(new StringBuilder()
				// Month is 0 based, just add 1
				.append(day).append("-").append(month + 1).append("-")
				.append(year));

	}

	/**
	 * Opens dialog picker, so the user can select image from the gallery. The
	 * result is returned in the method <code>onActivityResult()</code>
	 */
	public void selectImageFromGallery() {
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(Intent.createChooser(intent, "Select Picture"),
				PICK_IMAGE);

	}

	/**
	 * Retrieves the result returned from selecting image, by invoking the
	 * method <code>selectImageFromGallery()</code>
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
				&& null != data) {
			Uri selectedImage = data.getData();
			String[] filePathColumn = { MediaStore.Images.Media.DATA };

			Cursor cursor = getContentResolver().query(selectedImage,
					filePathColumn, null, null, null);
			cursor.moveToFirst();

			int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
			String picturePath = cursor.getString(columnIndex);
			getPictureName(picturePath);

			cursor.close();

			decodeFile(picturePath);

		}
	}

	/**
	 * The method decodes the image file to avoid out of memory issues. Sets the
	 * selected image in to the ImageView.
	 * 
	 * @param filePath
	 */
	public void decodeFile(String filePath) {
		// Decode image size
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filePath, o);

		// The new size we want to scale to
		final int REQUIRED_SIZE = 1024;

		// Find the correct scale value. It should be the power of 2.
		int width_tmp = o.outWidth, height_tmp = o.outHeight;
		int scale = 1;
		while (true) {
			if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
				break;
			width_tmp /= 2;
			height_tmp /= 2;
			scale *= 2;
		}

		// Decode with inSampleSize
		BitmapFactory.Options o2 = new BitmapFactory.Options();
		o2.inSampleSize = scale;
		bitmap = BitmapFactory.decodeFile(filePath, o2);

		Matrix matrix = new Matrix();
		matrix.postRotate(270);
		Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
				bitmap.getHeight(), matrix, true);

		Bitmap scaled = getResizedBitmap(rotated, 72, 72);

		image.setImageBitmap(scaled);

	}

	/**
	 * Given the picture path, the method sets the global variable ImageName
	 * 
	 * @param picturePath_val
	 */
	private void getPictureName(String picturePath_val) {
		if (null != picturePath_val && picturePath_val.length() > 0) {
			int endIndex = picturePath_val.lastIndexOf(".");
			if (endIndex != -1) {
				ImageName = picturePath_val.substring(0, endIndex); // not
																	// forgot to
																	// put check
																	// if(
																	// endIndex
																	// != -1)

			}
		}

	}

	public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {

		int width = bm.getWidth();
		int height = bm.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);
		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
				matrix, false);
		return resizedBitmap;

	}
	
	private void filesave(File file) throws IOException {
		FileOutputStream fileOutput = new FileOutputStream(file);
		InputStream inputStream = new ByteArrayInputStream(bs.toByteArray());//urlConnection.getInputStream();
		 	
		// create a buffer...
		byte[] buffer = new byte[2048];
		int bufferLength = 0; // used to store a temporary size of the
		// buffer
		// now, read through the input buffer and write the contents to
		// the file
		while ((bufferLength = inputStream.read(buffer)) > 0) {
			fileOutput.write(buffer, 0, bufferLength);
		}
		// close the output stream when done
		fileOutput.close();

	}

}
